package com.zh.opcua.milo;

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * Copyright (C) 广州中和互联网技术有限公司
 *
 * @author 范家微 fanjiawei@borche.cn
 * @date :2020/12/18 14:24
 */
public class OPCUAClientUtils {
	public static OpcUaClient createOpcUaClient() throws Exception {
		// 创建OPC UA的服务连接对象
		Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
		Files.createDirectories(securityTempDir);
		if (!Files.exists(securityTempDir)) {
			throw new Exception("不能够创建安全路径: " + securityTempDir);
		}
		KeyStoreLoader loader = new KeyStoreLoader().load(securityTempDir);
		//private static String EndPointUrl = "opc.tcp://192.168.0.4:4840";
		String EndPointUrl = "opc.tcp://127.0.0.1:49320";
		//String EndPointUrl = "opc.tcp://192.168.1.222:4840";
		//String EndPointUrl = "opc.tcp://192.168.1.151:49321";
		// 获取节点
		EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(EndPointUrl).get(10, TimeUnit.SECONDS);
		//过滤掉不需要的安全策略，选择一个自己需要的安全策略
		EndpointDescription endpoint = Arrays.stream(endpoints)
				// 根据安全策略过滤
				.filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getSecurityPolicyUri()))
				// 根据节点过滤
				//.filter(e -> e.getEndpointUrl().equals(EndPointUrl))
				.findFirst().orElseThrow(() -> new Exception("没有节点返回"));


		// 创建配置类，生成OPC客户端对象
		OpcUaClientConfig config = OpcUaClientConfig.builder()
				//.setApplicationName(LocalizedText.english("UA%20Server"))
				.setApplicationName(endpoint.getServer().getApplicationName())
				//.setApplicationUri("urn:FJW:Kepware.KEPServerEX.V6:UA%20Server")
				.setApplicationUri(endpoint.getServer().getApplicationUri())
				.setCertificate(loader.getClientCertificae())
				.setKeyPair(loader.getClientKeyPair())
				.setEndpoint(endpoint)
				// 设置客户端访问验证方式
				//.setIdentityProvider(new UsernameProvider("OPCUser", "123456"))
				.setIdentityProvider(new AnonymousProvider())
				.setRequestTimeout(Unsigned.uint(50000)).setSessionTimeout(Unsigned.uint(1000000))
				.build();
		OpcUaClient opcUaClient = new OpcUaClient(config);
		return opcUaClient;
	}
}
